~(function (F) {
    let moduleCache = {},
        setModule = function (moduleName, params, callback) {
            let _module, fn;
            if (moduleCache[moduleName]) {
                _module = moduleCache[moduleName];
                _module.status = 'loaded';
                _module.exports = callback ? callback.apply(_module, params) : null;
                while (fn = _module.onload.shift()) {
                    fn(_module.exports);
                }
            } else {
                callback && callback.apply(null, params);
            }
        },
        loadModule = function (moduleName, callback) {
            let _module;
            if (moduleCache[moduleName]) {
                _module = moduleCache[moduleName];
                if (_module.status === 'loaded') {
                    setTimeout(callback(_module.exports), 0);
                } else {
                    _module.onload.push(callback);
                }
            } else {
                moduleCache[moduleName] = {
                    moduleName: moduleName,
                    status: 'loading',
                    exports: null,
                    onload: [callback]
                };
                loadScript(getUrl(moduleName));
            }
        },
        getUrl = function (moduleName) {
            return String(moduleName).replace(/\.js$/g, '') + '.js';
        },
        loadScript = function (src) {
            let _script = document.createElement('script');
            _script.type = 'text/JavaScript';
            _script.charset = 'UTF-8';
            _script.async = true;
            _script.src = src;
            document.getElementsByTagName('head')[0].appendChild(_script);
        };
    F.module = function (url, modDeps, modCallback) {
        let args = [].slice.call(arguments),
            callback = args.pop(),
            deps = (args.length && args[args.length-1] instanceof Array) ? args.pop() : [],
            params = [],
            depsCount = 0;
        url = args.length ? args.pop() : null;
        if (deps.length) {
            for (let i = 0; i < deps.length; i++) {
                (function () {
                    depsCount++;
                    loadModule(deps[i], function (mod) {
                        params[i] = mod;
                        depsCount--;
                        if (depsCount === 0) {
                            setModule(url, params, callback);
                        }
                    })
                })(i);
            }
        }else{
            setModule(url, [], callback);
        }
    };
})((function () {
    return window.F = {};
})());

let data = {
    tagCloud: [
        {is_selected: true, title: '这是一本设计模式书', text: '设计模式'},
        {is_selected: false, title: '这是一本HTML书', text: 'HTML'},
        {is_selected: null, title: '这是一本CSS书', text: 'CSS'},
        {is_selected: '', title: '这是一本JavaScript书', text: 'JavaScript'}
    ]
};

F.module(['lib/template', 'lib/dom'], function (template, dom) {
    let str = template('demo_tag', data);
    dom.html('test', str);
});